const _toString = Object.prototype.toString

/**
 * 数据类型
 * @param {*} value 任意
 * @return {string}
 */
export function typeOf(value: any) {
  return _toString.call(value).slice(8, -1).toLowerCase()
}

export function isUndef(v: any) {
  return v === undefined || v === null
}

export function isDef(v: any) {
  return v !== undefined && v !== null
}

export function isObject(obj: any) {
  return obj !== null && typeof obj === 'object'
}

export function isNumber(v: any) {
  return v && typeof v === 'number'
}

export function isString(v: any) {
  return v && typeof v === 'string'
}

/**
 * 是否是对象
 * @param {*} obj 包含null
 * @return {boolean}
 */
export function isPlainObject(obj: any) {
  return _toString.call(obj) === '[object Object]'
}

/**
 * 是否是promise
 * @param {*} val 任意
 * @return {boolean}
 */
export function isPromise(val: any) {
  return isDef(val) && typeof val.then === 'function' && typeof val.catch === 'function'
}

/**
 * 是否是数组
 * @param {*} obj 待判断对象
 * @return {boolean}
 */
export function isArray(obj: any) {
  if (Array.isArray) {
    return Array.isArray(obj)
  }
  return _toString.call(obj) === '[object Array]'
}

/**
 * 判断对象是否为空
 * @param {*} obj 待判断对象
 * @return {boolean}
 */
export function isEmptyObject(obj: any) {
  if (isObject(obj) && JSON.stringify(obj) === '{}') {
    return true
  }
  return false
}

/**
 * 判断是否为空 undefined null '' 0 false NaN {} []都认为为空
 * @param {*} value 待判断对象
 */
export function isEmpty(value: any) {
  switch (typeof value) {
    case 'undefined':
      return true
    case 'string':
      if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length === 0) return true
      break
    case 'boolean':
      if (!value) return true
      break
    case 'number':
      if (value === 0 || Number.isNaN(value)) return true
      break
    case 'object':
      if (value === null || value.length === 0) return true
      return Object.keys(value).length === 0
  }
  return false
}
